package javabase.collection.Iterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess;

public class RandomAccessDemo {
	private int i;
	private static boolean randomAccessExists = false;
	public RandomAccessDemo(int i) {
		this.i = i;
	}
	@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("java.util.RandomAccess");
			randomAccessExists = true;
		} catch(Exception e) {
			randomAccessExists = false;
		}
		int SIZE = args.length > 0 ? Integer.parseInt(args[0]) : 100000;
		ArrayList arrayList = new ArrayList(SIZE);
		LinkedList linkedList = new LinkedList();
		RandomAccessDemo r;
		for (int i = 0; i < SIZE; i++) {
			arrayList.add(r = new RandomAccessDemo(i));
			linkedList.add(r);
		}
		all(arrayList, linkedList);
	}
	public static void all(List<?> list1, List<?> list2) {
		loopCounter(list1);
		loopCounter(list2);
		iterator(list1);
		iterator(list2);
		iteratorWithLoopCounter(list1);
		iteratorWithLoopCounter(list2);
		randomAccess(list1);
		randomAccess(list2);
	}
	
	public static long loopCounter(List<?> list) {
		long st = System.currentTimeMillis();
		int count = 0;
		for (int i = 0, n = list.size(); i < n; i++) {
			count += ((RandomAccessDemo) list.get(i)).i;
		}
		long time = System.currentTimeMillis() - st;
		System.out.println(list.getClass().getName() + "in loopCounter took:" + time +"millis to get result " + count);
		return time;
	}
	
	public static long iterator(List<?> list) {
		long st = System.currentTimeMillis();
		int count = 0;
		for (Iterator<?> iterator = list.iterator(); iterator.hasNext();) {
			count += ((RandomAccessDemo) iterator.next()).i;
		}
		long time = System.currentTimeMillis() - st;
		System.out.println(list.getClass().getName() + "in iterator took:" + time +"millis to get result " + count);
		return time;
	}
	
	public static long iteratorWithLoopCounter(List<?> list) {
		long st = System.currentTimeMillis();
		int count = 0;
		Iterator<?> iterator = list.iterator();
		for (int j = 0, n = list.size(); j < n; j++) {
			count += ((RandomAccessDemo) iterator.next()).i;
		}
		long time = System.currentTimeMillis() - st;
		System.out.println(list.getClass().getName() + "in iteratorWithLoopCounter took:" + time +"millis to get result " + count);
		return time;
	}
	
	public static long randomAccess(List<?> list) {
		if (randomAccessExists && (list instanceof RandomAccess)) {
			return loopCounter(list);
		}
		return iteratorWithLoopCounter(list);
	}
}
